namespace nwWCF
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.ServiceModel.Description;
    using System.Xml;

    /// <summary>
    /// Apply Cyclic Data Contract Serializer OperationBehavior
    /// </summary>
    internal class CyclicDataContractSerializer :
        DataContractSerializerOperationBehavior
    {
        #region Private Fields

        /// <summary>
        /// Max items in object graph.
        /// </summary>
        private readonly int maxItemsInObjectGraph;

        /// <summary>
        /// Whether ignore extention data object or not.
        /// </summary>
        private readonly bool ignoreExtensionDataObject;

        /// <summary>
        /// Whether preserve object references or not.
        /// </summary>
        private readonly bool preserveObjectReferences;

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="ApplyCyclicDataContractSerializerOperationBehavior"/> class.
        /// </summary>
        /// <param name="operationDescription">The operation description.</param>
        /// <param name="maxItemsInObjectGraph">The max items in object graph.</param>
        /// <param name="ignoreExtensionDataObject">if set to <c>true</c> [ignore extension data object].</param>
        /// <param name="preserveObjectReferences">if set to <c>true</c> [preserve object references].</param>
        public CyclicDataContractSerializer(
            OperationDescription operationDescription,
            int maxItemsInObjectGraph,
            bool ignoreExtensionDataObject,
            bool preserveObjectReferences)
            : base(operationDescription)
        {
            this.maxItemsInObjectGraph = maxItemsInObjectGraph;
            this.ignoreExtensionDataObject = ignoreExtensionDataObject;
            this.preserveObjectReferences = preserveObjectReferences;
        }

        /// <summary>
        /// Creates the serializer.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="name">The name.</param>
        /// <param name="ns">The ns.</param>
        /// <param name="knownTypes">The known types.</param>
        /// <returns>XmlObjectSerializer<see cref="XmlObjectSerializer"/> object</returns>
        public override XmlObjectSerializer CreateSerializer(
            Type type,
            string name,
            string ns,
            IList<Type> knownTypes)
        {
            return new DataContractSerializer(
                    type,
                    name,
                    ns,
                    knownTypes,
                    this.maxItemsInObjectGraph,
                    this.ignoreExtensionDataObject,
                    this.preserveObjectReferences,
                    null);
        }

        /// <summary>
        /// Creates the serializer.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="name">The name.</param>
        /// <param name="ns">The ns.</param>
        /// <param name="knownTypes">The known types.</param>
        /// <returns>XmlObjectSerializer <see cref="XmlObjectSerializer"/> object</returns>
        public override XmlObjectSerializer CreateSerializer(
            Type type,
            XmlDictionaryString name,
            XmlDictionaryString ns,
            IList<Type> knownTypes)
        {
            return new DataContractSerializer(
                    type,
                    name,
                    ns,
                    knownTypes,
                    this.maxItemsInObjectGraph,
                    this.ignoreExtensionDataObject,
                    this.preserveObjectReferences,
                    null);
        }
    }
}
